import websockets
import json
import asyncio
from datetime import datetime
from typing import List


class TaskManagerClient:
    def __init__(self):
        self.devices: List[dict] = []
        self.connections: List[websockets.WebSocketClientProtocol] = []

    async def verify_device(self, address: str) -> dict:
        """验证设备是否为有效的任务管理器"""
        try:
            uri = f"ws://{address}:81"
            async with websockets.connect(uri) as ws:
                print(address)
                # 发送设备验证请求
                await ws.send(json.dumps({"command": "identify"}))
                response = await asyncio.wait_for(ws.recv(), timeout=15)
                data = json.loads(response)

                if data.get("type") == "classroom_manager":
                    return {
                        "uri": uri,
                        "name": data.get("name", "Unknown"),
                        "ip": address
                    }
        except Exception as e:
            pass
        return None

    async def scan_network(self, base_ip: str = "192.168.1") -> None:
        """扫描局域网内的任务管理器设备"""
        print("开始扫描网络...")
        tasks = []
        for i in range(1, 255):
            ip = f"{base_ip}.{i}"
            tasks.append(self.verify_device(ip))

        results = await asyncio.gather(*tasks)
        self.devices = [device for device in results if device]
        print(f"找到 {len(self.devices)} 个设备")

    async def connect_devices(self) -> None:
        """连接到所有找到的设备"""
        print("\n正在连接设备...")
        for device in self.devices:
            try:
                print(device["uri"])
                ws = await websockets.connect(device["uri"])
                self.connections.append(ws)
                print(f"已连接: {device['name']} ({device['ip']})")
            except Exception as e:
                print(f"连接失败: {device['ip']} - {str(e)}")

    async def send_task(self, ws: websockets.WebSocketClientProtocol, task: dict) -> None:
        """发送任务到指定设备"""
        try:
            await ws.send(json.dumps(task))
            print(f"任务添加完毕")
        except Exception as e:
            print(f"发送失败: {str(e)}")

    async def user_interaction(self) -> None:
        """处理用户交互"""
        while True:
            # 显示设备列表
            print("\n可用设备:")
            for i, device in enumerate(self.devices):
                if i < len(self.connections):
                    status = "✓"
                else:
                    status = "✗"
                print(f"{i + 1}. [{status}] ({device['name']}) ({device['ip']})")

            # 选择设备
            try:
                selection = input("\n选择设备序号 (q退出): ").strip()
                if selection.lower() == 'q':
                    break

                index = int(selection) - 1
                if index < 0 or index >= len(self.devices):
                    print("无效序号")
                    continue

                if index >= len(self.connections):
                    print("设备未连接")
                    continue

                # 输入任务信息
                task = {
                    "command": "add_task",
                    "name": input("任务名称: "),
                    "start": input("开始时间 (YYYY-MM-DDTHH:MM:SS): "),
                    "end": input("结束时间 (YYYY-MM-DDTHH:MM:SS): ")
                }

                # 验证时间格式
                try:
                    datetime.fromisoformat(task["start"]).isoformat()
                    datetime.fromisoformat(task["end"]).isoformat()
                except ValueError:
                    print("错误的时间格式")
                    continue

                # 发送任务
                await self.send_task(self.connections[index], task)

            except ValueError:
                print("请输入有效数字")
            except Exception as e:
                print(f"发生错误: {str(e)}")

    async def run(self) -> None:
        """主运行流程"""
        await self.scan_network()
        if not self.devices:
            print("未找到任何设备")
            return

        await self.connect_devices()
        if not self.connections:
            print("没有可用连接")
            return

        await self.user_interaction()

        # 关闭所有连接
        for ws in self.connections:
            await ws.close()


if __name__ == "__main__":
    try:
        client = TaskManagerClient()
        asyncio.run(client.run())
    except KeyboardInterrupt:
        print("\n程序已终止")